home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / fax / src / faxd / FaxRequest.c++ < prev    next >
C/C++ Source or Header  |  1994-08-01  |  8KB  |  254 lines

  1. /*    $Header: /usr/people/sam/fax/faxd/RCS/FaxRequest.c++,v 1.38 1994/02/28 14:15:17 sam Rel $ */
  2. /*
  3.  * Copyright (c) 1990, 1991, 1992, 1993, 1994 Sam Leffler
  4.  * Copyright (c) 1991, 1992, 1993, 1994 Silicon Graphics, Inc.
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and 
  7.  * its documentation for any purpose is hereby granted without fee, provided
  8.  * that (i) the above copyright notices and this permission notice appear in
  9.  * all copies of the software and related documentation, and (ii) the names of
  10.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  11.  * publicity relating to the software without the specific, prior written
  12.  * permission of Sam Leffler and Silicon Graphics.
  13.  * 
  14.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  15.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  16.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  17.  * 
  18.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  19.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  20.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  21.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  22.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  23.  * OF THIS SOFTWARE.
  24.  */
  25. #include <ctype.h>
  26. #include <unistd.h>
  27. #include <syslog.h>
  28. #include <osfcn.h>
  29. #include <fcntl.h>
  30.  
  31. #include "FaxRequest.h"
  32. #include "config.h"
  33.  
  34. Regexp FaxRequest::jobidPat(FAX_QFILEPREF);
  35.  
  36. FaxRequest::FaxRequest(const fxStr& qf) : qfile(qf)
  37. {
  38.     tts = 0;
  39.     killtime = 0;
  40.     (void) jobidPat.Match(qf, qf.length(), 0);
  41.     int qfileTail = jobidPat.EndOfMatch();
  42.     jobid = qf.extract(qfileTail, qf.length()-qfileTail);
  43.     fp = NULL;
  44.     status = send_retry;
  45.     npages = 0;
  46.     dirnum = 0;
  47.     ntries = 0;
  48.     ndials = 0;
  49.     totdials = 0;
  50.     maxdials = (u_short) FAX_RETRIES;
  51.     notify = no_notice;
  52. }
  53.  
  54. FaxRequest::~FaxRequest()
  55. {
  56.     if (fp)
  57.     fclose(fp);
  58. }
  59.  
  60. fxBool
  61. FaxRequest::checkFile(const char* file)
  62. {
  63.     // XXX scan full pathname to avoid security holes (e.g. foo/../../..)
  64.     if (file[0] == '.' || file[0] == '/') {
  65.     syslog(LOG_ERR, "%s: Invalid data file \"%s\"; not in same directory",
  66.         (char*) qfile, file);
  67.     return FALSE;
  68.     }
  69.     int fd = open(file, 0);
  70.     if (fd == -1) {
  71.     syslog(LOG_ERR, "%s: Can not access data file \"%s\"",
  72.         (char*) qfile, file);
  73.     return FALSE;
  74.     }
  75.     close(fd);
  76.     return TRUE;
  77. }
  78.  
  79. #define    isCmd(cmd)    (strcasecmp(line, cmd) == 0)
  80.  
  81. // Return True for success, False for failure
  82. fxBool
  83. FaxRequest::readQFile(int fd)
  84. {
  85.     if (fd > -1)
  86.     fp = fdopen(fd, "r+w");
  87.     else
  88.     fp = fopen((char*) qfile, "r+w");
  89.     if (fp == NULL) {
  90.     syslog(LOG_ERR, "%s: open: %m", (char*) qfile);
  91.     return FALSE;
  92.     }
  93.     char line[1024];
  94.     char* cp;
  95.     while (fgets(line, sizeof (line) - 1, fp)) {
  96.     if (line[0] == '#')
  97.         continue;
  98.     if (cp = strchr(line, '\n'))
  99.         *cp = '\0';
  100.     char* tag = strchr(line, ':');
  101.     if (!tag) {
  102.         syslog(LOG_ERR, "%s: Malformed line \"%s\"", (char*) qfile, line);
  103.         return FALSE;
  104.     }
  105.     *tag++ = '\0';
  106.     while (isspace(*tag))
  107.         tag++;
  108.     if (isCmd("tts")) {        // time to send
  109.         tts = atoi(tag);
  110.         if (tts == 0)
  111.         tts = time(0);        // distinguish "now" from unset
  112.     } else if (isCmd("killtime")) {    // time to kill job
  113.         killtime = atoi(tag);
  114.     } else if (isCmd("number")) {    // dialstring
  115.         number = tag;
  116.     } else if (isCmd("external")) {    // displayable phone number
  117.         external = tag;
  118.     } else if (isCmd("sender")) {    // sender's name
  119.         sender = tag;
  120.     } else if (isCmd("mailaddr")) {    // return mail address
  121.         mailaddr = tag;
  122.     } else if (isCmd("jobtag")) {    // user-specified job tag
  123.         jobtag = tag;
  124.     } else if (isCmd("status")) {    // reason job is queued
  125.         notice = tag;
  126.     } else if (isCmd("resolution")) {// vertical resolution in dpi
  127.         resolution = atof(tag);
  128.     } else if (isCmd("npages")) {    // number of pages
  129.         npages = atoi(tag);
  130.     } else if (isCmd("dirnum")) {    // directory of next page to send
  131.         dirnum = atoi(tag);
  132.     } else if (isCmd("ntries")) {    // # attempts to send current page
  133.         ntries = atoi(tag);
  134.     } else if (isCmd("ndials")) {    // # consecutive failing calls
  135.         ndials = atoi(tag);
  136.     } else if (isCmd("totdials")) {    // total # calls
  137.         totdials = atoi(tag);
  138.     } else if (isCmd("maxdials")) {    // max total # calls
  139.         maxdials = atoi(tag);
  140.     } else if (isCmd("pagewidth")) {// page width in pixels
  141.         pagewidth = atoi(tag);
  142.     } else if (isCmd("pagelength")) {// page length in mm
  143.         pagelength = atof(tag);
  144.     } else if (isCmd("pagehandling")) {// page analysis info
  145.         pagehandling = tag;
  146.     } else if (isCmd("modem")) {    // outgoing modem to use
  147.         modem = tag;
  148.     } else if (isCmd("notify")) {    // email notification
  149.         if (strcmp(tag, "when done") == 0) {
  150.         notify = when_done;
  151.         } else if (strcmp(tag, "when requeued") == 0) {
  152.         notify = when_requeued;
  153.         } else if (strcmp(tag, "none") == 0) {
  154.         notify = no_notice;
  155.         } else {
  156.         syslog(LOG_ERR, "job %s: Invalid notify value \"%s\"\n",
  157.             (char*) qfile, tag);
  158.         }
  159.     } else if (isCmd("postscript")) {    // postscript document
  160.         if (!checkFile(tag))
  161.         return FALSE;
  162.         files.append(tag);
  163.         ops.append(FaxSendOp(send_postscript));
  164.     } else if (isCmd("!postscript")) {    // saved postscript document
  165.         if (!checkFile(tag))
  166.         return FALSE;
  167.         files.append(tag);
  168.         ops.append(FaxSendOp(send_postscript_saved));
  169.     } else if (isCmd("tiff")) {        // tiff document
  170.         if (!checkFile(tag))
  171.         return FALSE;
  172.         files.append(tag);
  173.         ops.append(FaxSendOp(send_tiff));
  174.     } else if (isCmd("!tiff")) {        // saved tiff document
  175.         if (!checkFile(tag))
  176.         return FALSE;
  177.         files.append(tag);
  178.         ops.append(FaxSendOp(send_tiff_saved));
  179.     } else if (isCmd("poll")) {        // polling request
  180.         files.append(tag);
  181.         ops.append(FaxSendOp(send_poll));
  182.     } else
  183.         syslog(LOG_INFO, "%s: ignoring unknown command line \"%s: %s\"",
  184.         (char*) qfile, line, tag);
  185.     }
  186.     if (tts == 0) {
  187.     syslog(LOG_INFO, "%s: not ready to send yet", (char*) qfile);
  188.     return FALSE;
  189.     }
  190.     if (number == "" || sender == "" || mailaddr == "") {
  191.     syslog(LOG_ERR, "%s: Malformed job description, "
  192.         "missing number|sender|mailaddr", (char*) qfile);
  193.     return FALSE;
  194.     }
  195.     if (killtime == 0) {
  196.     syslog(LOG_ERR, "%s: No kill time, or time is zero", (char*) qfile);
  197.     return (FALSE);
  198.     }
  199.     if (modem == "")
  200.     modem = MODEM_ANY;
  201.     if (files.length() > 0)
  202.     return TRUE;
  203.     syslog(LOG_ERR, "%s: No files to send (number \"%s\")",
  204.     (char*) qfile, (char*) number);
  205.     return FALSE;
  206. }
  207.  
  208. void
  209. FaxRequest::writeQFile()
  210. {
  211.     rewind(fp);
  212.     fprintf(fp, "modem:%s\n", (char*) modem);
  213.     fprintf(fp, "tts:%u\n", tts);
  214.     fprintf(fp, "killtime:%u\n", killtime);
  215.     fprintf(fp, "number:%s\n", (char*) number);
  216.     fprintf(fp, "external:%s\n", (char*) external);
  217.     fprintf(fp, "sender:%s\n", (char*) sender);
  218.     fprintf(fp, "resolution:%g\n", resolution);
  219.     fprintf(fp, "npages:%d\n", npages);
  220.     fprintf(fp, "dirnum:%d\n", dirnum);
  221.     fprintf(fp, "ntries:%d\n", ntries);
  222.     fprintf(fp, "ndials:%d\n", ndials);
  223.     fprintf(fp, "totdials:%d\n", totdials);
  224.     fprintf(fp, "maxdials:%d\n", maxdials);
  225.     fprintf(fp, "pagewidth:%d\n", pagewidth);
  226.     fprintf(fp, "pagelength:%g\n", pagelength);
  227.     fprintf(fp, "pagehandling:%s\n", (char*) pagehandling);
  228.     fprintf(fp, "status:%s\n", (char*) notice);
  229.     fprintf(fp, "mailaddr:%s\n", (char*) mailaddr);
  230.     fprintf(fp, "jobtag:%s\n", (char*) jobtag);
  231.     if (notify == when_requeued)
  232.     fprintf(fp, "notify:when requeued\n");
  233.     else if (notify == when_done)
  234.     fprintf(fp, "notify:when done\n");
  235.     static const char* opNames[3] = { "postscript", "tiff", "poll" };
  236.     for (u_int i = 0, n = files.length(); i < n; i++) {
  237.     const char* op = "";
  238.     switch (ops[i]) {
  239.     case send_tiff:            op = "tiff"; break;
  240.     case send_tiff_saved:        op = "!tiff"; break;
  241.     case send_postscript:        op = "postscript"; break;
  242.     case send_postscript_saved:    op = "!postscript"; break;
  243.     case send_poll:            op = "poll"; break;
  244.     }
  245.     fprintf(fp, "%s:%s\n", op, (char*) files[i]);
  246.     }
  247.     fflush(fp);
  248.     if (ftruncate(fileno(fp), ftell(fp)) < 0)
  249.     syslog(LOG_ERR, "%s: truncate failed: %m", (char*) qfile);
  250.     // XXX probably should fsync, but not especially portable
  251. }
  252.  
  253. fxIMPLEMENT_PrimArray(FaxSendOpArray, FaxSendOp);
  254.